﻿/**
 * Copyright (c) 2009 Rtistique Pty. Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.dnamique.bzoo
{
	import com.blitzagency.xray.logger.XrayLog;
	import com.rtistique.bzoo.Bzoo;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flexunit.framework.TestCase;
	import flexunit.framework.TestSuite;
	import flash.events.Event;
	/**
	 * @author Bachir El Khoury
	 * @version 1.0
	 */
	public class BzooTest extends TestCase
	{
		private var log:XrayLog = new XrayLog();
		
		private var data:Array = [
		{name:"Bob",
		  gender:"M",
		  married:"No",
		  age:25,
		  state:"NY",
		  favorite_foods:["pizza","tacos"]},
		 {name:"Joyce",
		  gender:"F",
		  married:"No",
		  age:29,
		  state:"WA",
		  favorite_foods:["salad","cheese sticks"]},
		 {name:"Dan",
		  gender:"M",
		  married:"No",
		  age:29,
		  state:"MT",
		  favorite_foods:["pizza","hamburgers","BLTs"]},
		 {name:"Sarah",
		  gender:"F",
		  married:"No",
		  age:21,
		  state:"ID",
		  favorite_foods:["pizza","sushi"]}
		  ];

		public function BzooTest(methodName:String) 
		{
			super(methodName);
		}
		public static function suite():TestSuite
		{
			var bzooTS:TestSuite = new TestSuite();
			/**
			 * Find All Tests
			 */
			bzooTS.addTest(new BzooTest("find_allNoCriteria_returnAll"));
			bzooTS.addTest(new BzooTest("find_allSingleCondition_returnAll"));
			bzooTS.addTest(new BzooTest("find_allMultiConditions_returnAll"));
			bzooTS.addTest(new BzooTest("find_allLessThan_returnAll"));
			bzooTS.addTest(new BzooTest("find_allGreaterThan_returnAll"));
			bzooTS.addTest(new BzooTest("find_allEquals_returnAll"));
			bzooTS.addTest(new BzooTest("find_allAscOrder_returnAllAscOrder"));
			bzooTS.addTest(new BzooTest("find_allDescOrder_returnAllDescOrder"));
			bzooTS.addTest(new BzooTest("find_allNumOrder_returnAllNumOrder"));
			bzooTS.addTest(new BzooTest("find_allGreaterThanAscOrder_returnAllOrder"));
			bzooTS.addTest(new BzooTest("find_allSpecifiedFields_returnSpecifiedFields"));
			bzooTS.addTest(new BzooTest("find_allFieldsConditionOrdered_returnFilteredFieldsOrdered"));
			/**
			 * Find First Tests
			 */
			bzooTS.addTest(new BzooTest("find_first_returnFirst"));
			bzooTS.addTest(new BzooTest("find_firstCondition_returnFirst"));
			bzooTS.addTest(new BzooTest("find_firstConditionField_returnFirst"));
			bzooTS.addTest(new BzooTest("find_countCondition_returnNumber"));
			/**
			 * Insert tests
			 */
			bzooTS.addTest(new BzooTest("insert_singleObject_returnFirst"));
			bzooTS.addTest(new BzooTest("insert_multipleObjects_returnAll"));
			
			bzooTS.addTest(new BzooTest("order_ASC_returnAscArray"));
			bzooTS.addTest(new BzooTest("order_DESC_returnDescArray"));
			bzooTS.addTest(new BzooTest("order_NUMERIC_returnNumArray"));
			/**
			 * Delete tests
			 */
			bzooTS.addTest(new BzooTest("remove_singleObject_return3Results"));
			bzooTS.addTest(new BzooTest("remove_multipleObjects_return2results"));
			bzooTS.addTest(new BzooTest("removeByIndex_singleObject_returnResultsLength3"));
			/**
			 * Update tests
			 */
			bzooTS.addTest(new BzooTest("update_singleObject_returnAll"));
			bzooTS.addTest(new BzooTest("update_multipleObjects_returnAll"));
			
			/**
			 * Yaml tests
			 */
			bzooTS.addTest(new BzooTest("find_allYAML_returnAll"));
			bzooTS.addTest(new BzooTest("find_allYAMLMultiConditions_returnAll"));

			/**
			 * JSON tests
			 */
			bzooTS.addTest(new BzooTest("find_allJSON_returnAll"));
			bzooTS.addTest(new BzooTest("find_allJSONMultiConditions_returnAll"));
			
			bzooTS.addTest(new BzooTest("persistent_returnAll"));
			
			return bzooTS;
		}
		public function persistent_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data, "amf", true, "test3");
			var result:Object = bzoo.find(Bzoo.FIND_ALL);
			assertEquals("Expecting injected data to be equal to data", "Bob", result[0].name);
			assertEquals("Expecting injected data to be equal to data", "Sarah", result[3].name);
			assertEquals("Expecting injected data to be equal to data", 4, result.length);
		}
		
		public function find_allYAML_returnAll():void
		{
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, function():void { 
					var yaml:String = loader.data.toString();
					var bzoo:Bzoo = new Bzoo(yaml, Bzoo.TYPE_YAML);
					var result:Object = bzoo.find(Bzoo.FIND_ALL);
					assertEquals("Expecting injected data to be equal to data", "Bob", result[0].name);
					assertEquals("Expecting injected data to be equal to data", "Sarah", result[3].name);
					assertEquals("Expecting injected data to be equal to data", 4, result.length);				
				} ); 
			loader.load(new URLRequest("sample.yaml"));	
		}
		public function find_allYAMLMultiConditions_returnAll():void
		{
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, function():void { 
					var yaml:String = loader.data.toString();
					var bzoo:Bzoo = new Bzoo(yaml, Bzoo.TYPE_YAML);
					var result:Object = bzoo.find(Bzoo.FIND_ALL, { conditions:[ { field:"age", equal:29 }, { field:"gender", equal:"F" } ] } );
					assertEquals("Expecting equal values", "Joyce", result[0].name);
					assertEquals("Expecting 1 result", 1, result.length);				
				} ); 
				
			loader.load(new URLRequest("sample.yaml"));
		}
		public function find_allJSON_returnAll():void
		{
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, function():void { 
					var bzoo:Bzoo = new Bzoo(loader.data, Bzoo.TYPE_JSON);
					var result:Object = bzoo.find(Bzoo.FIND_ALL);
					assertEquals("Expecting injected data to be equal to data", "Bob", result[0].name);
					assertEquals("Expecting injected data to be equal to data", "Sarah", result[3].name);
					assertEquals("Expecting injected data to be equal to data", 4, result.length);				
				} ); 
				
			loader.load(new URLRequest("json.txt"));	
		}
		public function find_allJSONMultiConditions_returnAll():void
		{
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, function():void { 
					var bzoo:Bzoo = new Bzoo(loader.data, Bzoo.TYPE_JSON);
					var result:Object = bzoo.find(Bzoo.FIND_ALL, { conditions:[ { field:"age", equal:29 }, { field:"gender", equal:"F" } ] } );
					assertEquals("Expecting equal values", "Joyce", result[0].name);
					assertEquals("Expecting 1 result", 1, result.length);				
				} ); 
				
			loader.load(new URLRequest("json.txt"));
		}		
		public function update_singleObject_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			bzoo.update({conditions:{field:"name", equal:"Sarah"}}, {field:"name", equal:"Bachir"});
			var result:Object = bzoo.find("all",{conditions:{field:"name", equal:"Bachir"}});
			assertEquals("Expecting equal values", "Bachir", result[0].name);
		}
		public function update_multipleObjects_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			bzoo.update({conditions:{field:"age", greaterThan:"25"}}, {field:"married", equal:"YES"});
			var result:Object = bzoo.find();
			assertEquals("Expecting equal values", "YES", result[1].married);
			assertEquals("Expecting equal values", "YES", result[2].married);
		}
		public function remove_singleObject_return3Results():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			bzoo.remove({conditions:{field:"name", equal:"Sarah"}});
			var result:Object = bzoo.find();
			assertEquals("Expecting equal values", 3, result.length);
		}
		public function remove_multipleObjects_return2results():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			bzoo.remove({conditions:{field:"age", equal:"29"}});
			var result:Object = bzoo.find();
			assertEquals("Expecting equal values", 2, result.length);
		}
		public function removeByIndex_singleObject_returnResultsLength3():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.removeByIndex(1);
			assertEquals("Expecting equal values", "Dan", result[1].name);
			assertEquals("Expecting equal values", 3, result.length);
		}
		public function insert_multipleObjects_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			bzoo.insert( [ { name:"Bachir", gender:"M", married:"YES", age: 28, state:"NSW", favorite_food:["Moussaka", "hamburger", "McDonalds"] },
							{ name:"Christina", gender:"F", married:"YES", age: 25, state:"NSW", favorite_food:["Air", "sushi", "salads"] }]);
			var result:Object = bzoo.find();
			assertEquals("Expecting equal values", "Bachir", result[4].name);
			assertEquals("Expecting equal values", "Christina", result[5].name);
		}
		public function insert_singleObject_returnFirst():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			bzoo.insert( { name:"Bachir", gender:"M", married:"YES", age: 28, state:"NSW", favorite_food:["Moussaka", "hamburger", "McDonalds"] } );
			var result:Object = bzoo.find(Bzoo.FIND_FIRST, { conditions: { field:"name", equal:"Bachir" }} );
			assertEquals("Expecting equal values", "Bachir", result.name);
			assertEquals("Expecting equal values", 28, result.age);
		}
		/**
		 * Find All Tests
		 */
		public function find_allNoCriteria_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL);
			assertEquals("Expecting injected data to be equal to data", "Bob", result[0].name);
			assertEquals("Expecting injected data to be equal to data", "Sarah", result[3].name);
			assertEquals("Expecting injected data to be equal to data", 4, result.length);
		}
		
		public function find_allSingleCondition_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, { conditions: { field:"age", equal:29 }} );
			assertEquals("Expecting equal values", "Joyce", result[0].name);
			assertEquals("Expecting equal values", "Dan", result[1].name);
			assertEquals("Expecting 2 results", 2, result.length);
		}
		public function find_allGreaterThan_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, {conditions:{field:"age", greaterThan:"21" }});
			assertEquals("Expecting equal values", "Bob", result[0].name);
			assertEquals("Expecting equal values", "Joyce", result[1].name);
			assertEquals("Expecting equal values", "Dan", result[2].name);
			assertEquals("Expecting 3 results", 3, result.length);
		}
		public function find_allLessThan_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, {conditions:{field:"age", lessThan:"29"}});
			assertEquals("Expecting equal values", "Bob", result[0].name);
			assertEquals("Expecting equal values", "Sarah", result[1].name);
			assertEquals("Expecting 2 results", 2, result.length);
		}
		public function find_allEquals_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, {conditions:{field:"age", equal:"29"}});
			assertEquals("Expecting equal values", "Joyce", result[0].name);
			assertEquals("Expecting equal values", "Dan", result[1].name);
			assertEquals("Expecting 2 results", 2, result.length);
		}
		public function find_allMultiConditions_returnAll():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, { conditions:[ { field:"age", equal:29 }, { field:"gender", equal:"F" } ] } );
			assertEquals("Expecting equal values", "Joyce", result[0].name);
			assertEquals("Expecting 1 result", 1, result.length);
		}
		public function find_allAscOrder_returnAllAscOrder():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, { orderBy: { field:"name", order:Bzoo.ASCENDING }} );
			assertEquals("Expecting equal values", "Bob", result[0].name);
			assertEquals("Expecting equal values", "Dan", result[1].name);
			assertEquals("Expecting equal values", "Joyce", result[2].name);
			assertEquals("Expecting equal values", "Sarah", result[3].name);
		}
		public function find_allDescOrder_returnAllDescOrder():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, { orderBy: { field:"name", order:Bzoo.DESCENDING }} );
			assertEquals("Expecting equal values", "Sarah", result[0].name);
			assertEquals("Expecting equal values", "Joyce", result[1].name);
			assertEquals("Expecting equal values", "Dan", result[2].name);
			assertEquals("Expecting equal values", "Bob", result[3].name);
		}
		public function find_allNumOrder_returnAllNumOrder():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, { orderBy: { field:"age", order:Bzoo.NUMERIC}} );
			assertEquals("Expecting equal values", "21", result[0].age);
			assertEquals("Expecting equal values", "25", result[1].age);
			assertEquals("Expecting equal values", "29", result[2].age);
			assertEquals("Expecting equal values", "29", result[3].age);
		}
		public function find_allGreaterThanAscOrder_returnAllOrder():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, { conditions:{field:"age",greaterThan:25}, orderBy: { field:"name", order:Bzoo.ASCENDING}} );
			assertEquals("Expecting equal values", "Dan", result[0].name);
			assertEquals("Expecting equal values", "Joyce", result[1].name);
			assertEquals("Expecting equal values", 2, result.length);;
		}
		public function find_allSpecifiedFields_returnSpecifiedFields():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, { fields:["name", "age"] } );
			assertUndefined("Expecting undefined ", result[0].gender);
			assertEquals("Expecting Equals", "Bob", result[0].name);
			assertEquals("Expecting Equals", "21", result[3].age);
		}
		public function find_allFieldsConditionOrdered_returnFilteredFieldsOrdered():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_ALL, { fields:["name", "state"], conditions:[ { field:"age", greaterThan:"21" } ], orderBy: { field:"state", order:Bzoo.ASCENDING } } );
			assertUndefined("Expecting undefined ", result[0].gender);
			assertEquals("Expecting Equals", "Dan", result[0].name);
			assertEquals("Expecting Equals", "Bob", result[1].name);
			assertEquals("Expecting Equals", "Joyce", result[2].name);
		}
		/**
		 * Order Tests
		 */
		public function order_ASC_returnAscArray():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Array = bzoo.orderBy("name", Bzoo.ASCENDING);
			assertEquals("Expecting equal values", "Bob", result[0].name);
			assertEquals("Expecting equal values", "Dan", result[1].name);
			assertEquals("Expecting equal values", "Joyce", result[2].name);
			assertEquals("Expecting equal values", "Sarah", result[3].name);
		}
		public function order_DESC_returnDescArray():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Array = bzoo.orderBy("state", Bzoo.DESCENDING);
			assertEquals("Expecting equal values", "WA", result[0].state);
			assertEquals("Expecting equal values", "NY", result[1].state);
			assertEquals("Expecting equal values", "MT", result[2].state);
			assertEquals("Expecting equal values", "ID", result[3].state);
		}
		public function order_NUMERIC_returnNumArray():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Array = bzoo.orderBy("age", Bzoo.NUMERIC);
			assertEquals("Expecting equal values", "21", result[0].age);
			assertEquals("Expecting equal values", "25", result[1].age);
			assertEquals("Expecting equal values", "29", result[2].age);
			assertEquals("Expecting equal values", "29", result[3].age);
		}
		/**
		 * Find First tests
		 */
		public function find_first_returnFirst():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_FIRST);
			assertEquals("Expecting Equal Values", "Bob", result.name);
		}
		public function find_firstCondition_returnFirst():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_FIRST, { conditions:{ field:"age", equal:"29" } } );
			assertEquals("Expecting Equal Values", "Joyce", result.name);
		}
		public function find_firstConditionField_returnFirst():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_FIRST, { conditions:{ field:"age", equal:"29" } , fields:["favorite_foods"] } );
			assertUndefined("Expecting Undefined Value", result.name);
			assertEquals("Expecting Equal Values", "salad", result.favorite_foods[0]);
			assertEquals("Expecting Equal Values", "cheese sticks", result.favorite_foods[1]);
		}		
		/**
		 * Find Count tests
		 */
		public function find_countCondition_returnNumber():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_COUNT, { conditions:{ field:"age", equal:"29" } } );
			assertEquals("Expecting Equal Values", 2, result);
		}
		
		public function find_count_returnNumberOfRecordsThatMatchCriteria():void
		{
			var bzoo:Bzoo = new Bzoo(data);
			var result:Object = bzoo.find(Bzoo.FIND_COUNT, {conditions:{name:"Dan"}});
			assertEquals("Expecting Equal Values", "Dan", result.name);
		}	
	}
}